<?php

namespace App\Http\Controllers\Entity\Column;

use App\Classes\Publish\Publication;
use App\Http\Controllers\Controller;
use App\Http\Requests\Entity\Column\CollistRequest;
use App\Jobs\Publish\CollistJob;
use App\Models\Application\Pagetpl;
use App\Models\Application\Paneltpl;
use App\Models\Application\TermType;
use App\Models\Common\EntityData\Channel\Sp;
use App\Models\Entity\Column\Collist;
use App\Models\Entity\Column\Column;
use App\Models\Entity\Tag\tag;
use App\Repositories\Entity\Column\CollistRepository;
use Encore\Admin\Controllers\ModelForm;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Flash;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Response;
use Validator;

class CollistController extends Controller
{
    use ModelForm;

    /** @var  CollistRepository */
    private $collistRepository;

    public function __construct(CollistRepository $collistRepo)
    {
        $this->collistRepository = $collistRepo;
    }

    /**
     * Display a listing of the Collist.
     *
     * @return Response
     */
    public function index(Request $request)
    {
        return Admin::content(function (Content $content) use ($request) {

            $content->header(__('entity.column.collists.index_header'));
            $content->description(__('entity.column.collists.index_description'));

            $content->body($this->grid($request));
        });
    }

    /**
     * Show the form for creating a new Collist.
     *
     * @return Response
     */
    public function create()
    {
        return Admin::content(function (Content $content) {

            $content->header(__('entity.column.collists.create_header'));
            $content->description(__('entity.column.collists.create_description'));

            $content->body($this->form());

        });
    }

    /**
     * Store a newly created Collist in storage.
     *
     * @param CollistRequest $request
     *
     * @return Response
     */
    public function store(CollistRequest $request)
    {
        $input = $request->all();
        // logo图片
        $image = $request->file('img'); //使用laravel 自带的request类来获取一下文件.
        if ($image) {
            if ($image->isValid()) {
                // 允许上传的图片格式
                $allowed_extensions = ["png", "jpg", "gif", "jpeg"];
                if ($image->getClientOriginalExtension() && !in_array($image->getClientOriginalExtension(), $allowed_extensions)) {
                    return ['error' => 'You may only upload png, jpg, jpeg or gif.'];
                }
                $bgRealPath = $image->getRealPath(); //临时文件的绝对路径
                // 获得图片的扩展名
                $extension = $image->getClientOriginalExtension();
                // 获取上传图片的文件名
                // $imagesName = $image->getClientOriginalName();
                // 重新命名上传文件名字
                $newImageName = md5(time()) . random_int(5, 5) . "." . $extension;
                // 上传图片
                $uploadConfig = config('custom.base.upload.collist');
                $driver       = $uploadConfig['driver'];
                $dir          = $uploadConfig['dir'];
                $rootDir      = config('filesystems.disks.' . $driver . '.upload');
                // 图片的完整路径
                $fullPath     = $rootDir . '/' . $dir . '/' . $newImageName;
                $input['img'] = $fullPath;

                $bool = Storage::disk($driver)->put($fullPath, file_get_contents($bgRealPath));
            }
        }
        // 背景图片
        $backgroundImage = $request->file('bg'); //使用laravel 自带的request类来获取一下文件.
        if ($backgroundImage) {
            if ($backgroundImage->isValid()) {
                // 允许上传的图片格式
                $allowed_extensions = ["png", "jpg", "gif", "jpeg"];
                if ($backgroundImage->getClientOriginalExtension() && !in_array($backgroundImage->getClientOriginalExtension(), $allowed_extensions)) {
                    return ['error' => 'You may only upload png, jpg, jpeg or gif.'];
                }
                $bgRealPath = $backgroundImage->getRealPath(); //临时文件的绝对路径
                // 获得图片的扩展名
                $bgExtension = $backgroundImage->getClientOriginalExtension();
                // 获取上传图片的文件名
                // $imagesName = $image->getClientOriginalName();
                // 重新命名上传文件名字
                $newBackgroudImageName = md5(time()) . random_int(5, 5) . "." . $bgExtension;
                // 上传图片
                $uploadConfig = config('custom.base.upload.collist');
                $driver       = $uploadConfig['driver'];
                $dir          = $uploadConfig['dir'];
                $rootDir      = config('filesystems.disks.' . $driver . '.upload');
                // 图片的完整路径
                $bgFullPath  = $rootDir . '/' . $dir . '/' . $newBackgroudImageName;
                $input['bg'] = $bgFullPath;

                $bool = Storage::disk($driver)->put($bgFullPath, file_get_contents($bgRealPath));
            }
        }

        $collist = $this->collistRepository->create($input);
        if ($collist) {
            // 保存当前栏目列表的标签
            if (is_array($request->get('tags'))) {
                $collist->tags()->attach(array_filter($request->get('tags')));
            }
        }
        Flash::success(__('entity.column.collists.saved_success'));

        return Input::get('_previous_') ? redirect(Input::get('_previous_')) : redirect(route('entity.column.collists.index'));

    }

    /**
     * Display the specified Collist.
     *
     * @param  int $id
     *
     * @return Response
     */
    public function show($id)
    {
        $collist = $this->collistRepository->findWithoutFail($id);

        if (empty($collist)) {
            Flash::error(__('entity.column.collists.not_found'));

            return redirect(route('entity.column.collists.index'));
        }

        return view('entity.column.collists.show')->with('collist', $collist);

    }

    /**
     * Show the form for editing the specified Collist.
     *
     * @param  int $id
     *
     * @return Response
     */
    public function edit($id)
    {
        $collist = $this->collistRepository->findWithoutFail($id);

        if (empty($collist)) {
            Flash::error(__('entity.column.collists.not_found'));

            return redirect(route('entity.column.collists.index'));
        }
        return Admin::content(function (Content $content) use ($id, $collist) {

            $content->header(__('entity.column.collists.edit_header'));
            $content->description(__('entity.column.collists.edit_description'));

            $content->body($this->form()->edit($id));
            $range = $collist->range ? $collist->range : 0;
            $content->row(view('entity.column.collist.edit', ['range' => $range, 'tpl_id' => $collist->tpl_id]));

        });
    }

    /**
     * Update the specified Collist in storage.
     *
     * @param  int              $id
     * @param CollistRequest $request
     *
     * @return Response
     */
    public function update($id, Request $request)
    {
        $collist = $this->collistRepository->findWithoutFail($id);

        if (empty($collist)) {
            Flash::error(__('entity.column.collists.not_found'));

            return redirect(route('entity.column.collists.index'));
        }
        $input = $request->all();

        if (array_key_exists('_file_del_', $input)) {
            $bgtype       = $request->post('bg');
            $imgtype      = $request->post('img');
            $uploadConfig = config('custom.base.upload.collist');
            $driver       = $uploadConfig['driver'];
            $dir          = $uploadConfig['dir'];
            if ($bgtype === '_file_del_') {
                $imgUrl = $collist->bg;
                if ($flag = Storage::disk($driver)->delete($imgUrl)) {
                    $collist->bg = null;
                    $collist->save();
                    return response()->json(['message' => '图片删除成功!', 'status' => $flag]);
                }
            } elseif ($imgtype === '_file_del_') {
                $imgUrl = $collist->img;
                if ($flag = Storage::disk($driver)->delete($imgUrl)) {
                    $collist->img = null;
                    $collist->save();
                    return response()->json(['message' => '图片删除成功!', 'status' => $flag]);
                }

            }
            return response()->json(['message' => '图片删除失败!', 'status' => $flag]);
        }

        $sValidators = [
            // 'collist_no' => 'required|max:100|unique:collists,collist_no,' . $id,
            'name'       => 'required|max:100',
            'title'      => 'max:100',
            'subtitle'   => 'max:100',
            'short_desc' => 'max:100',
            // 'img'        => 'max:200',
            'listorder'  => 'required|numeric',
        ];

        $validators = [];

        // 判断是否行内编辑,只有下线的可以编辑
        $status = Collist::where(['online_status' => 0, 'id' => $id])->first();
        if ($status) {
            $input = $this->handleEditable($input);
        }

        // 动态判断校验
        foreach ($input as $key => $value) {
            if (isset($sValidators[$key])) {
                $validators[$key] = $sValidators[$key];
            }
        }

        // 定义校验, 没有移到request
        $validator = Validator::make($input, $validators, [
            // 'required' => ':attribute 不能为空',
        ], [
            'name'       => '名称',
            'title'      => '标题',
            'subtitle'   => '副标题',
            'short_desc' => '描述',
            'listorder'  => '排序',
        ]
        );

        // 校验
        if ($validator->fails()) {
            return back()->withErrors($validator)->withInput();
        }

        // 排序
        if ($this->handleOrderable($id, $input)) {
            return response([
                'status'  => true,
                'message' => trans('admin::lang.update_succeeded'),
            ]);
        }

        $image = $request->file('img'); //使用laravel 自带的request类来获取一下文件.
        if ($image) {
            if ($image->isValid()) {
                // 允许上传的图片格式
                $allowed_extensions = ["png", "jpg", "gif", "jpeg"];
                if ($image->getClientOriginalExtension() && !in_array($image->getClientOriginalExtension(), $allowed_extensions)) {
                    return ['error' => 'You may only upload png, jpg, jpeg or gif.'];
                }
                $bgRealPath = $image->getRealPath(); //临时文件的绝对路径
                // 获得图片的扩展名
                $extension = $image->getClientOriginalExtension();
                // 获取上传图片的文件名
                // $imagesName = $image->getClientOriginalName();
                // 重新命名上传文件名字
                $newImageName = md5(time()) . random_int(5, 5) . "." . $extension;
                // 上传图片
                $uploadConfig = config('custom.base.upload.collist');
                $driver       = $uploadConfig['driver'];
                $dir          = $uploadConfig['dir'];
                $rootDir      = config('filesystems.disks.' . $driver . '.upload');
                // $rootDir      = config('filesystems.disks.' . $driver . '.root');

                // 图片的完整路径
                $fullPath = $rootDir . '/' . $dir . '/' . $newImageName;

                // $rootDir  = config('filesystems.disks.'.$driver.'.root');
                // $fullPath = $dir . '/' . $newImageName;
                // 修改input
                // $input['img'] = $rootDir . $fullPath;

                $input['img'] = $fullPath;

                // 2017/08/22 modify
                // 删除原先存储的图片
                $flag = Storage::disk($driver)->delete($collist->img);

                $bool = Storage::disk($driver)->put($fullPath, file_get_contents($bgRealPath));
            }
        }

        // 背景图片
        $backgroundImage = $request->file('bg'); //使用laravel 自带的request类来获取一下文件.
        if ($backgroundImage) {
            if ($backgroundImage->isValid()) {
                // 允许上传的图片格式
                $allowed_extensions = ["png", "jpg", "gif", "jpeg"];
                if ($backgroundImage->getClientOriginalExtension() && !in_array($backgroundImage->getClientOriginalExtension(), $allowed_extensions)) {
                    return ['error' => 'You may only upload png, jpg, jpeg or gif.'];
                }
                $bgRealPath = $backgroundImage->getRealPath(); //临时文件的绝对路径
                // 获得图片的扩展名
                $bgExtension = $backgroundImage->getClientOriginalExtension();
                // 获取上传图片的文件名
                // $imagesName = $image->getClientOriginalName();
                // 重新命名上传文件名字
                $newBackgroudImageName = md5(time()) . random_int(5, 5) . "." . $bgExtension;
                // 上传图片
                $uploadConfig = config('custom.base.upload.collist');
                $driver       = $uploadConfig['driver'];
                $dir          = $uploadConfig['dir'];
                $rootDir      = config('filesystems.disks.' . $driver . '.upload');
                // 图片的完整路径
                $bgFullPath  = $rootDir . '/' . $dir . '/' . $newBackgroudImageName;
                $input['bg'] = $bgFullPath;
                // 删除原先存储的图片
                $flag = Storage::disk($driver)->delete($collist->bg);
                $bool = Storage::disk($driver)->put($bgFullPath, file_get_contents($bgRealPath));
            }
        }
        $collist = $this->collistRepository->update($input, $id);
        if ($collist) {
            // 保存当前栏目列表的标签
            if (is_array($request->get('tags'))) {
                // $collist->tags()->detach();
                $collist->tags()->sync(array_filter($request->get('tags')));
            }
        }
        Flash::success(__('entity.column.collists.updated_success'));

        return Input::get('_previous_') ? redirect(Input::get('_previous_')) : redirect(route('entity.column.collists.index'));
    }

    /**
     * Remove the specified Collist from storage.
     *
     * @param  int $id
     *
     * @return Response
     */
    public function destroy($id)
    {
        // 根据 `,` 判断传递过来的是单个id还是多个id
        if (substr_count($id, ',') >= 1) {
            $id = explode(",", $id);
        }
        // 如果是数组则进行批量删除
        if (is_array($id)) {
            // 只有下线且下线发布的才能删除
            $id = Collist::whereIn('id', $id)->pluck('id')->toArray();
            if ($flag = $this->collistRepository->batchDelete('id', $id)) {
                return response()->json(['message' => __('entity.column.collists.deleted_success'), 'status' => $flag]);
            }
        }

        $collist = $this->collistRepository->findWithoutFail($id);

        if (empty($collist)) {
            Flash::error(__('entity.column.collists.not_found'));

            return redirect(route('entity.column.collists.index'));
        }

        if ($flag = $this->collistRepository->delete($id)) {
            // 取消与标签的关联
            $collist->tags()->detach();
            $uploadConfig = config('custom.base.upload.collist');
            $driver       = $uploadConfig['driver'];
            $deleteImg    = Storage::disk($driver)->delete($collist->bg);
            $deleteImg    = Storage::disk($driver)->delete($collist->img);
            return response()->json(['message' => __('entity.column.collists.deleted_success'), 'status' => $flag]);
        } else {
            return response()->json(['message' => __('base.deleted.error'), 'status' => $flag]);
        }
    }

    /**
     * [form description]
     * @return {[type]} [description]
     */
    protected function form()
    {
        return Admin::form(Collist::class, function (Form $form) {

            $form->display('id', 'ID');
            $form->text('name', '名称')->help('必填');
            $form->text('title', '标题');
            $form->text('subtitle', '副标题');
            $sps = Sp::pluck('name', 'id');
            $form->select('sp_id', 'Sp服务商')->options($sps);
            $termTypes = TermType::pluck('name', 'id');
            $form->select('term_type_id', '设备类型')->options($termTypes)->default(1);
            $form->select('level', '栏目级数')->options(array(
                1 => 'list0',
                2 => 'list1',
                3 => 'list2',
            ))->default('1');
            $form->select('range', 'range')->options(array(
                '0' => '选择',
                '1' => 'area',
                '2' => 'page',
                '3' => 'app',
                '4' => 'list',
            ))->load('tpl_id', route('entity.column.collists.tpls'), 'id', 'title')->help('选中range时模板不能为空');;
            $paneltpls = Paneltpl::pluck('title', 'id')->toArray();
            $form->select('tpl_id', '模板')->options(array_merge(['0' => '选择'], $paneltpls));
            // $Columns = Column::pluck('name', 'id');
            // $form->multipleSelect('cols', '栏目')->options($Columns);
            // 背景图
            $form->image('bg', '背景图')->removable();
            // message
            $form->text('message', 'message');
            $form->textarea('data', '数据');
            $form->text('short_desc', '简介');
            $form->textarea('long_desc', '详述');
            $form->image('img', 'logo')->removable();
            $tags = tag::pluck('name', 'id');
            $form->multipleSelect('tags', '标签')->options($tags);
            $form->number('listorder', '排序');

            $form->display('created_at', __('base.created_at'));
            $form->display('updated_at', __('base.updated_at'));

        });
    }

    /**
     * [grid description]
     * @return {[type]} [description]
     */
    protected function grid(Request $request)
    {

        return Admin::grid(Collist::class, function (Grid $grid) use ($request) {
            // 考虑是否需要scope和排序
            // $grid->model()->orderBy('listorder', 'asc');

            // 表格中的按钮
            $grid->actions(function ($actions) {
                $publish_down_status = $actions->row->publish_down_status;
                $publish_status      = $actions->row->publish_status;
                $online_status       = $actions->row->online_status;
                $id                  = $actions->getKey();

                // 编辑按钮
                if (Admin::user()->cannot('entity.column.collists.edit')) {
                    $actions->disableEdit();
                }
                // 删除按钮
                if (Admin::user()->cannot('entity.column.collists.destroy')) {
                    $actions->disableDelete();
                }
                $url = route('application.collist_datas.index', ['collist_id' => $id]);
                $actions->prepend('<a href ="' . $url . '" title="数据编辑"><i class="fa fa-list" title="栏目列表数据"></i></a>');
            });

            //添加按钮
            if (Admin::user()->cannot('entity.column.collists.create')) {
                $grid->disableCreation();
            }

            // 导出按钮
            if (Admin::user()->cannot('entity.column.collists.export')) {
                $grid->disableExport();
            }

            // 批量操作
            $grid->tools(function ($tools) {
                $tools->batch(function ($batch) {
                    // 批量删除按钮
                    if (Admin::user()->cannot('entity.column.collists.batch_destroy')) {
                        $batch->disableDelete();
                    }
                });

                // 批量按钮
                $tools->batch(function ($batch) {
                    // 批量删除按钮
                    if (Admin::user()->cannot('entity.column.collists.batch_destroy')) {
                        $batch->disableDelete();
                    }
                });
            });

            // $grid->column('collist_no', '编号')->sortable();
            $grid->column('id', 'ID')->sortable();
            $grid->column('sp.name', 'Sp服务商')->sortable();
            $grid->column('name', '名称')->sortable()->editable();
            $grid->column('title', '标题')->sortable()->editable();
            $grid->column('subtitle', '副标题')->sortable()->editable();
            $grid->column('termType.name', '设备类型')->sortable();
            $grid->column('level', '栏目级数')->display(function ($val) {
                switch ($val) {
                    case '1':
                        return '<span class="badge bg-green">list0</span>';
                        break;
                    case '2':
                        return '<span class="badge bg-green">list1</span>';
                        break;
                    case '3':
                        return '<span class="badge bg-green">list2</span>';
                        break;
                    default:
                        return '';
                        break;
                }
            });
            $grid->column('range', 'range')->display(function ($val) {
                switch ($val) {
                    case '1':
                        return '<span class="badge bg-green">area</span>';
                        break;
                    case '2':
                        return '<span class="badge bg-green">page</span>';
                        break;
                    case '3':
                        return '<span class="badge bg-green">app</span>';
                        break;
                    case '4':
                        return '<span class="badge bg-green">list</span>';
                        break;
                    default:
                        return '';
                        break;
                }
            });
            $grid->column('tpl_id', '模板')->display(function ($val) {
                $returnName = '';
                switch ($this->range) {
                    case '1':
                        $returnName = Paneltpl::where(['id' => $val])->value('title');
                        break;
                    default:
                        $returnName = Pagetpl::where(['id' => $val])->value('title');
                        break;
                }
                return empty($returnName) ? '' : $returnName;
            });
            $uploadConfig = config('custom.base.upload.collist');
            $driver       = $uploadConfig['driver'];
            $dir          = $uploadConfig['dir'];
            $uploadHosts  = config('custom.base.host');
            $host         = $uploadHosts[$driver];
            // 背景图
            $grid->column('bg', '背景图')->image($host);
            // 信息
            $grid->column('message', 'message')->sortable();

            $grid->tags('标签')->pluck('name')->label();
            $grid->column('data', '数据')->sortable();
            $grid->column('short_desc', '简介')->sortable();
            $grid->column('long_desc', '详述')->sortable()->display(function ($val) {
                if (!empty($val)) {
                    return Str::limit($val, 20);
                }
                return '';
            });
            $grid->column('img', 'logo')->image($host);
            $grid->column('listorder', '排序')->sortable()->editable();
            /**
             * 过滤处理
             */
            $grid->filter(function ($filter) {
                // 禁用id查询框
                // $filter->disableIdFilter();
                // 设备类型
                $tmpTermTypes = TermType::pluck('title', 'id');
                $filter->equal('term_type_id', '设备类型')->select($tmpTermTypes);
                // 所属栏目
                $tempColumns = Column::pluck('name', 'id');
                $filter->where(function ($query) {
                    $input = $this->input;
                    $query->whereHas('cols', function ($query) use ($input) {
                        $query->where('column_id', '=', "{$input}");
                    });

                }, '所属栏目')->select($tempColumns);

                // 编号
                // $filter->like('collist_no', '编号');
                // 名称
                $filter->like('name', '名称');
                // 标题
                $filter->like('title', '标题');
                // 上线时间
                $filter->between('online_at', '上线时间')->datetime();
                // 下线时间
                $filter->between('offline_at', '下线时间')->datetime();
            });
        });
    }

    /**
     * 全部上线功能
     */
    public function allUp()
    {
        if (Admin::user()->cannot('entity.column.collists.all_up')) {
            return response()->json(['taskid' => 0, 'content' => '您的权限不够!']);
        }
        // 统计需要处理的任务的总数
        $total_num = DB::table('collists as a')
            ->join('collist_columns as b', 'a.id', '=', 'b.collist_id')
            ->where(['a.online_status' => 0, 'a.publish_down_status' => 1])
            ->pluck('a.id')->unique()->count();
        $notices = [];
        // 已经上线的ids
        $notices[] = [Collist::where(['online_status' => 1])->pluck('id'), 'ID为以下的栏目列表已经上线: '];
        // 还未下线发布的ids
        $notices[] = [Collist::where(['publish_down_status' => 0])->pluck('id'), 'ID为以下的栏目列表还未下线发布: '];
        // 没有栏目的ids
        $notices[] = [DB::table('collists as a')
                ->whereNotExists(function ($query) {
                    $query->select(DB::raw(1))
                        ->from('collist_columns as b')
                        ->whereRaw('a.id = b.collist_id');
                })
                ->whereNull('deleted_at')
                ->pluck('a.id'),
            'ID为以下的栏目列表下面没有栏目: ',
        ];
        // 拼装提示信息
        $oparation  = '栏目列表上线';
        $totalNum   = Collist::count();
        $successNum = $total_num;
        $failNum    = $totalNum - $successNum;
        $content    = Publication::makeNoticeInfo($oparation, $totalNum, $successNum, $failNum, $notices);
        if (!$total_num) {
            return response()->json(['taskid' => 0, 'content' => $content]);
        }
        $data   = ['task_type' => '栏目列表上线', 'user_id' => Admin::user()->id, 'total_num' => $total_num];
        $taskid = Publication::insertTasks($data);
        dispatch(new CollistJob(['dispatch', 'up'], '', $taskid));
        return response()->json(['taskid' => $taskid, 'content' => $content]);
    }

    /**
     * 全部下线功能
     */
    public function allDown()
    {
        if (Admin::user()->cannot('entity.column.collists.all_down')) {
            return response()->json(['taskid' => 0, 'content' => '您的权限不够!']);
        }
        // 统计需要处理的任务的总数
        // $total_num = Publication::getTotalNum(new Collist(), ['online_status' => 1]);
        $result = Publication::getTotalNum(new Collist(), [
            [['online_status' => 1], 'ID为以下栏目列表还没上线'],
        ], '栏目列表下线');
        list($total_num, $content) = $result;
        if (!$total_num) {
            return response()->json(['taskid' => 0, 'content' => $content]);
        }
        $data   = ['task_type' => '栏目列表下线', 'user_id' => Admin::user()->id, 'total_num' => $total_num];
        $taskid = Publication::insertTasks($data);
        dispatch(new CollistJob(['dispatch', 'down'], '', $taskid));
        return response()->json(['taskid' => $taskid, 'content' => $content]);
    }

    /**
     * 发布功能,由于是全部发布,整个操作放入队列
     */
    public static function publish(Request $request)
    {
        if (Admin::user()->cannot('entity.column.collists.publish')) {
            return response()->json(['taskid' => 0, 'content' => '您的权限不够!']);
        }
        // 统计需要处理的任务的总数
        // $total_num = Publication::getTotalNum(new Collist(), ['online_status' => 1, 'publish_status' => 0]);
        $result = Publication::getTotalNum(new Collist(), [
            [['online_status' => 1], 'ID为以下栏目列表还未上线: '],
            [['publish_status' => 0], 'ID为以下栏目列表已经上线发布: '],
        ], '栏目列表发布');
        list($total_num, $content) = $result;
        if (!$total_num) {
            return response()->json(['taskid' => 0, 'content' => $content]);
        }
        $data = ['task_type' => '栏目列表发布', 'user_id' => Admin::user()->id, 'total_num' => $total_num];
        // 任务表插入一条记录
        $taskid = Publication::insertTasks($data);
        dispatch(new CollistJob(['dispatch', 'publish'], '', $taskid));
        return response()->json(['taskid' => $taskid, 'content' => $content]);
    }

    /**
     * 下线发布功能
     */
    public function publishDown(Request $request)
    {
        if (Admin::user()->cannot('entity.column.collists.publish_down')) {
            return response()->json(['taskid' => 0, 'content' => '您的权限不够!']);
        }
        // 统计需要处理的任务的总数
        // $total_num = Publication::getTotalNum(new Collist(), ['online_status' => 0, 'publish_down_status' => 0]);
        $result = Publication::getTotalNum(new Collist(), [
            [['online_status' => 0], 'ID为以下栏目列表还未下线: '],
            [['publish_down_status' => 0], 'ID为以下栏目列表已经下线发布: '],
        ], '栏目列表下线发布');
        list($total_num, $content) = $result;
        if (!$total_num) {
            return response()->json(['taskid' => 0, 'content' => $content]);
        }
        $data = ['task_type' => '栏目列表下线发布', 'user_id' => Admin::user()->id, 'total_num' => $total_num];
        // 任务表插入一条记录
        $taskid = Publication::insertTasks($data);
        dispatch(new CollistJob(['dispatch', 'publishDown'], '', $taskid));
        return response()->json(['taskid' => $taskid, 'content' => $content]);
    }

    /**
     * 单个,批量上下线功能,单个发布功能
     */
    public function batchModerate(Request $request)
    {
        $user_id = Admin::user()->id;
        switch ($request->action) {
            // 上线
            case 'up':
                if (Admin::user()->cannot('entity.column.collists.up')) {
                    return response()->json(['status' => 'error', 'content' => '您的权限不够!']);
                }
                $acceptIds = $request->ids;
                //  $ids = Publication::myfilter(new Collist(), $acceptIds, ['online_status' => 0, 'publish_down_status' => 1]);
                $hasColumnIds = $total_num = DB::table('collists as a')
                    ->join('collist_columns as b', 'a.id', '=', 'b.collist_id')
                    ->where(['a.online_status' => 0, 'a.publish_down_status' => 1])
                    ->whereIn('a.id', $acceptIds)
                    ->pluck('a.id')->unique();
                // 查询不能上线的ids,及其原因
                $notices = [];
                // 已经上线的ids
                $alreadyOnlineIds = Collist::where(['online_status' => 1])->whereIn('id', $request->ids)->pluck('id');
                if ($alreadyOnlineIds->first()) {
                    $notices[] = [$alreadyOnlineIds, 'ID为以下的栏目列表已经上线'];
                }
                // 还未下线发布的ids
                $notPublishDownIds = Collist::where(['publish_down_status' => 0])->whereIn('id', $request->ids)->pluck('id');
                if ($notPublishDownIds->first()) {
                    $notices[] = [$notPublishDownIds, 'ID为以下的栏目列表还未下线发布'];
                }
                // 没有栏目的ids
                $hasNoColumnIds = DB::table('collists as a')
                    ->whereNotExists(function ($query) {
                        $query->select(DB::raw(1))
                            ->from('collist_columns as b')
                            ->whereRaw('a.id = b.collist_id');
                    })
                    ->whereIn('a.id', $request->ids)
                    ->pluck('a.id');
                if ($hasNoColumnIds->first()) {
                    $notices[] = [$hasNoColumnIds, 'ID为以下的栏目列表下面没有栏目'];
                }
                // 拼装提示信息
                $oparation  = '栏目列表上线';
                $totalNum   = count($acceptIds);
                $successNum = $hasColumnIds->count();
                $failNum    = $totalNum - $successNum;
                $content    = Publication::makeNoticeInfo($oparation, $totalNum, $successNum, $failNum, $notices);
                if (!$hasColumnIds->first()) {
                    return response()->json(['status' => 'error', 'content' => $content]);
                }
                // 如果栏目列表的栏目为空,不能上线
                // 查询出有多少栏目列表有栏目
                // $hasColumnIds = CollistColumn::whereIn('collist_id', $ids)->pluck('collist_id')->unique();
                $result = Publication::updateMany(new Collist(), $hasColumnIds, [
                    'online_status'       => 1,
                    'publish_down_status' => 0,
                    'user_id'             => $user_id,
                    'online_at'           => date('Y-m-d H:i:s'),
                ]);
                return response()->json(['status' => 'success', 'content' => $result ? $content : '上线操作失败']);
            // 发布
            case 'publish':
                if (Admin::user()->cannot('entity.column.collists.publish')) {
                    return response()->json(['status' => 'error', 'content' => '您的权限不够!']);
                }
                //  $ids = Publication::myfilter(new Collist(), $request->ids, ['online_status' => 1, 'publish_status' => 0]);
                $result = Publication::myfilter(new Collist(), $request->ids, [
                    [['online_status' => 1], 'ID为以下栏目列表还未上线: '],
                    [['publish_status' => 0], 'ID为以下栏目列表已经上线发布: '],
                ], '栏目列表发布');
                list($ids, $content) = $result;
                if (!$ids->first()) {
                    return response()->json(['status' => 'error', 'content' => $content]);
                }
                // 如果是批量放入队列中处理
                if (count($ids) > 1) {
                    $data   = ['task_type' => '栏目列表发布', 'user_id' => $user_id, 'total_num' => count($ids)];
                    $taskid = Publication::insertTasks($data);
                    dispatch(new CollistJob(['publish'], $ids, $taskid));
                    $url = route('entity.column.collists.progress');
                    return response()->json(['status' => 'queue', 'content' => $content, 'taskid' => $taskid, 'url' => $url]);
                }
                // 如果是单条数据发布
                $collists      = Collist::whereIn('id', $ids)->with('cols')->get();
                $collist_datas = CollistJob::makeCollists($collists);
                $result1       = Publication::insertApi('collists', $collist_datas);
                $result2       = Publication::updateMany(new Collist(), $ids, [
                    'publish_status' => 1,
                    'user_id'        => $user_id,
                ]);
                $content = ($result1 && $result2) ? $content : '发布失败!';
                return response()->json(['status' => 'success', 'content' => $content]);
            // 下线
            case 'down':
                if (Admin::user()->cannot('entity.column.collists.down')) {
                    return response()->json(['status' => 'error', 'content' => '您的权限不够!']);
                }
                //  $ids = Publication::myfilter(new Collist(), $request->ids, ['online_status' => 1]);
                $result = Publication::myfilter(new Collist(), $request->ids, [
                    [['online_status' => 1], 'ID为以下栏目列表还没上线'],
                ], '栏目列表下线');
                list($ids, $content) = $result;
                if (!$ids->first()) {
                    return response()->json(['status' => 'error', 'content' => $content]);
                }
                $result = Publication::updateMany(new Collist(), $ids, [
                    'online_status'  => 0,
                    'publish_status' => 0,
                    'user_id'        => $user_id,
                    'offline_at'     => date('Y-m-d H:i:s'),
                ]);
                return response()->json(['status' => 'success', 'content' => $result ? $content : '下线操作失败']);
            // 下线发布
            case 'publishDown':
                if (Admin::user()->cannot('entity.column.collists.publish_down_one_or_more')) {
                    return response()->json(['status' => 'error', 'content' => '您的权限不够!']);
                }
                //  $ids = Publication::myfilter(new Collist(), $request->ids, ['online_status' => 0, 'publish_down_status' => 0]);
                $result = Publication::myfilter(new Collist(), $request->ids, [
                    [['online_status' => 0], 'ID为以下栏目列表还未下线: '],
                    [['publish_down_status' => 0], 'ID为以下栏目列表已经下线发布: '],
                ], '栏目列表下线发布');
                list($ids, $content) = $result;
                if (!$ids->first()) {
                    return response()->json(['status' => 'error', 'content' => $content]);
                }
                /*
                 * 删除接口库中对应的数据
                 * 这里有两种可能的情况
                 * 1.资源还没有上线发布就被下线, 接口库没有还没有这个资源
                 * 2.资源已经上线发布过, 接口库中有这个资源
                 * 所以在删除接口库中的数据时, 需要先判断接口库中是否有对应数据, 有则返回删除操作的结果, 没有则直接返回true
                 */
                $collistsCount = DB::connection('interface')->table('collists')->whereIn('collistid', $ids)->count();
                if ($collistsCount) {
                    // 删除接口库中对应的数据
                    $result1 = Publication::deleteApi('collists', 'collistid', $ids);
                } else {
                    $result1 = true;
                }
                // 更新状态
                $result2 = Publication::updateMany(new Collist(), $ids, [
                    'publish_down_status' => 1,
                    'user_id'             => $user_id,
                ]);
                return response()->json(['status' => 'success', 'content' => $result1 && $result2 ? $content : '下线发布失败!']);
        }
    }

    /**
     * 查询进度
     */
    public function queryProgress(Request $request)
    {
        $taskid = (int) $request->input('taskid');
        return Publication::progress($taskid);
    }

    /**
     * 根据range获取模板
     * @param  Request $request [description]
     * @return [type]           [description]
     */
    public function getTplByRange(Request $request)
    {
        $dataId     = $request->get('q');
        $returnData = [];

        switch ($dataId) {
            case '1':
                $returnData = Paneltpl::get(['title', 'id'])->toArray();
                break;

            default:
                $returnData = Pagetpl::get(['title', 'id'])->toArray();
                break;
        }
        return array_merge([['id' => '0', 'title' => '选择']], $returnData);

    }

    /**
     * ajax请求回填数据
     * @param  [type]  $range   [description]
     * @param  Request $request [description]
     * @return [type]           [description]
     */
    public function getReasourceData($range, Request $request)
    {
        $datas = [];
        switch ($range) {
            case '1':
                $datas = Paneltpl::get(['title', 'id'])->toArray();
                break;
            default:
                $datas = Pagetpl::get(['title', 'id'])->toArray();
                break;
        }
        return response()->json(['content' => array_merge([['id' => '0', 'title' => '选择']], $datas), 'status' => true]);
    }
}
